use tracing::{info, error};

mod config;
mod modbus;
mod collector;
mod storage;
mod error;
mod api;
mod write_handler;

use config::ConfigManager;
use collector::DataCollector;
use storage::DataStorage;
use api::ApiServer;
use write_handler::WriteHandler;
use modbus::ModbusClientManager;
use error::Result;

#[tokio::main]
async fn main() -> Result<()> {
    // 初始化日志
    tracing_subscriber::fmt::init();
    
    info!("Starting Modbus Data Collector System");
    
    // 初始化配置管理器
    let config_manager = ConfigManager::new("config.xlsx").await?;
    
    // 初始化数据存储
    let storage = DataStorage::new().await?;
    
    // 初始化Modbus客户端管理器
    let modbus_manager = ModbusClientManager::new();
    
    // 初始化写指令处理器
    let mut write_handler = WriteHandler::new(
        config_manager.clone(),
        modbus_manager.clone(),
        storage.clone(),
    );
    
    // 启动写处理器
    write_handler.start().await?;
    let write_handler_arc = std::sync::Arc::new(write_handler);
    
    // 初始化数据采集器
    let mut collector = DataCollector::new(config_manager.clone(), storage.clone()).await?;
    
    // 初始化API服务器
    let api_server = ApiServer::new(storage.clone()).await?
        .with_write_handler(write_handler_arc.clone());
    
    // 启动各个服务
    let collector_handle = tokio::spawn(async move {
        collector.start().await
    });
    
    let api_handle = tokio::spawn(async move {
        api_server.start().await
    });
    
    // 等待服务结束
    tokio::select! {
        result = collector_handle => {
            if let Err(e) = result {
                error!("Collector service error: {}", e);
            }
        }
        result = api_handle => {
            if let Err(e) = result {
                error!("API service error: {}", e);
            }
        }
        _ = tokio::signal::ctrl_c() => {
            info!("Received shutdown signal, gracefully stopping services");
            
            // 关闭存储
            if let Err(e) = storage.close().await {
                error!("Error closing storage: {}", e);
            }
            
            info!("System shutdown completed");
        }
    }
    
    Ok(())
}